/*
 * console_cmd_handler.cpp
 *
 *  Created on: Nov 13, 2013
 *      Author: killerg
 */

#include "server_deps.h"
#include "server_console.h"
#include "client_session.h"
#include "server.h"
#include "server_cfg.h"
#include "game_logic/game_cfg.h"
#include "game_logic/player_data.h"
#include "game_logic/givebackmgr.h"

#include "share/net_s.h"
#include "share/clock.h"
#include "share/connection_mgr.h"

#include "game_logic/arena.h"
#include "game_logic/player_mgr.h"
#include "game_logic/rank_mgr.h"

#include <sys/socket.h>

std::string cmd_stat(Arg &arg, void* dummy) {
    g_console->_stat = !g_console->_stat;

    return "success";
}

std::string cmd_prof(Arg &arg, void* dummy) {
    g_console->_prof = !g_console->_prof;

    return "success";
}

std::string cmd_online(Arg &arg, void* dummy) {
    std::string buffer;
    g_sessmgr->base::connmgr.map_trans.for_each([&buffer](tran_s* tran, client_session_t* &sess){
        sockaddr_in addr;
        socklen_t addrlen = sizeof(addr);
        getpeername(sess->_trans->fd, (sockaddr*)&addr, &addrlen);
        char buff[100];
        evutil_inet_ntop(AF_INET, &addr.sin_addr, buff, 100);
        buffer.append(fmt_cstr("%s:%d\n", buff, ntohs(addr.sin_port)));
    });
    return buffer.c_str();
}

std::string cmd_shut(Arg &arg, void* dummy) {
    g_svr.status = co::ESS_Shuting;
    return "success";
}

std::string cmd_mask(Arg &arg, void* dummy) {
    int mask = get_int64_arg(arg, "-m", 15);
    g_console->_mask_s = mask;
    return "success";
}
std::string cmd_ar(Arg &arg, void* dummy) {
    bool r = get_int64_arg(arg, "-r", 1) != 0;
    g_arena->set_rewarding(r);
    return "success";
}

std::string cmd_core(Arg &arg, void* dummy) {
    *(int*)0 = 0;
    return "core";
}

std::string cmd_reward(Arg &arg, void* dummy) {
    return "success";
}

std::string cmd_maxclient(Arg &arg, void* dummy) {
	int maxclient = get_int_arg(arg, "-n", 1000);
	if (maxclient <= 0 || maxclient > 10000) {
		return "bad arg";
	}
	g_cfg->MaxClient = maxclient;
    return "success";
}

std::string cmd_rank(Arg &arg, void* dummy) {
	g_rank->rank_timer = 0.0f;

    return "success";
}

std::string cmd_cfgreload(Arg &arg, void* dummy) {
	g_game_cfg->destroy();
	g_game_cfg->init();

    return "success";
}
std::string cmd_occupy(Arg &arg, void* dummy) {
	g_console->_occupy_enabled = !g_console->_occupy_enabled;

    return "success";
}

std::string cmd_saveallplayer(Arg &arg, void* dummy) {

	Json::Value json;
	for (auto &itr : g_playermgr->stubs) {
		if (itr.second->player) {
			Json::Value p;
			itr.second->player->save(p);
			json.append(p);
		}
	}
	bool res = g_dbf->set("__allplaye", json, [](db_error_t err){
		assert(err == DBE_Success);
	});
	assert(res);

    return "success";
}

std::string cmd_giveback(Arg &arg, void* dummy) {
	g_svr.giveback->cur_index = 0;
	return "success";
}

bool svr_console_t::init() {
    if (!console_t2::init_net())
        return false;

    bool rtv = true;
    rtv = rtv && console_t2::reg("stat", "", cmd_stat);
    rtv = rtv && console_t2::reg("online", "", cmd_online);
    rtv = rtv && console_t2::reg("prof", "", cmd_prof);
    rtv = rtv && console_t2::reg("shut", "", cmd_shut);
    rtv = rtv && console_t2::reg("mask", "m:", cmd_mask);
    rtv = rtv && console_t2::reg("ar", "r:", cmd_ar);
    rtv = rtv && console_t2::reg("core", "", cmd_core);
    rtv = rtv && console_t2::reg("reward", "", cmd_reward);
    rtv = rtv && console_t2::reg("maxclient", "n:", cmd_maxclient);
    rtv = rtv && console_t2::reg("rank", "n:", cmd_rank);
    rtv = rtv && console_t2::reg("cfgreload", "", cmd_cfgreload);
    rtv = rtv && console_t2::reg("occupy", "", cmd_occupy);
    rtv = rtv && console_t2::reg("saveallplayer", "", cmd_saveallplayer);
    rtv = rtv && console_t2::reg("giveback", "", cmd_giveback);

    _stat = true;
    _prof = true;
    _occupy_enabled = true;

    _mask_f = E|W|I;
    _mask_s = E|W|I|C;

    watch_n("run_sec", [this]()->int{ return int(g_clock->eclipse); });
    watch_n("serverid", [this]()->int{ return int(g_cfg->ServerId); });


    return rtv;
}

void svr_console_t::destroy() {
    console_t2::destroy();
}

void svr_console_t::update() {
    if (_prof && g_clock->sec_jump) {
        update_watcher();
        UTIL_LOG(C, "\n%s", watch_ss.str().c_str());
    }

    console_t2::update();
}
